#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "appglobal.h"
#include "urlrecogniser.h"
#include "urlsniffer.h"
#include "addurldialog.h"
#include "progressdialog.h"
#include "getfromwebdialog.h"
#include "diskmap.h"
#include <QClipboard>
#include <QNetworkAccessManager>
#include <QDebug>
#include <QWebView>
#include <QWebFrame>
#include <QFile>
#include <QTime>

MainWindow::MainWindow(QWidget* parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow) {
    this->ui->setupUi(this);
    this->ui->treeUrls->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
    this->ui->treeUrls->setRootIsDecorated(false);
    this->ui->treeUrls->setSortingEnabled(true);
    this->ui->buttonGetFromClipboard->setIcon(QIcon(":/images/close.png"));

    this->dlgAdd = new AddUrlDialog(this);
    this->dlgProgress = new ProgressDialog(this);
    this->dlgGetFromWeb = new GetFromWebDialog(this);

    connect(this->ui->webView, &QWebView::loadFinished, this, &MainWindow::on_webview_load_finished);
    connect(this->ui->webView, &QWebView::loadStarted, this, &MainWindow::on_webView_load_started);
    connect(this->ui->webView, &QWebView::loadProgress, this, &MainWindow::on_webView_load_progress);
}

MainWindow::~MainWindow() {
    delete ui;
}

void MainWindow::on_sniffer_progressChanged(int pgr) {
    this->dlgProgress->setProgress(pgr);
}

// 提取真实链接完成, 填到表里去
void MainWindow::on_sniffer_finished() {
    YDUrlSniffer* sniffer = reinterpret_cast<YDUrlSniffer*>(this->sender());
    QTreeWidget* widget = this->ui->treeUrls;

    YDUrlSniffer::result_t& r = sniffer->results();
    for (auto p : r) {
        for (auto q : p.second) {
            QList<QTreeWidgetItem*> lst = widget->findItems(q.first, Qt::MatchFixedString, 2);
            if (!lst.isEmpty()) {
                if (q.second != "") {
                    lst.first()->setText(3, g.unescape(q.second));
                } else {
                    lst.first()->setText(3, "提取错误");
                }
            }
        }
    }

    sniffer->deleteLater();
    this->dlgProgress->accept();
}

// 从剪贴板获取
void MainWindow::on_buttonGetFromClipboard_clicked() {
    this->ui->treeUrls->clear();

    QClipboard* cpb = qApp->clipboard();
    QString str = cpb->text();

    qDebug() << "text in clipboard: " << str;

    if (!str.isEmpty()) {
        str = g.unescape(str);
        YDUrlRecogniser::url_map_t map = g.urlRecogniser->recogniseUrl(str);

        //qDebug() << "unescaped text in clipboard: " << str;

#ifndef NDEBUG
        QString filename = "C:\\ydhelperdebug\\" + QTime::currentTime().toString("hh_mm_ss_zzz") + ".cpb";
        QFile f(filename, this);
        f.open(QIODevice::ReadWrite);
        f.write(str.toUtf8());
        f.close();
#endif

        for (auto p : map) {
            for (auto s : p.second) {
                QTreeWidgetItem* item = new QTreeWidgetItem;

                item->setFlags(item->flags() | Qt::ItemIsEditable);

                item->setText(0, g.diskMap->getText(p.first));
                item->setIcon(0, *g.diskMap->getIcon(p.first));
                item->setData(0, Qt::UserRole, QVariant(p.first)); // 存储网盘类型，以备以后使用
                item->setCheckState(1, Qt::Checked);
                item->setText(2, s);
                this->ui->treeUrls->addTopLevelItem(item);
            }
        }
    }
}

// 删除选定的任务
void MainWindow::on_buttonRemoveUrl_clicked() {
    QTreeWidget* widget = this->ui->treeUrls;
    QList<QTreeWidgetItem*> lst = widget->selectedItems();

    for (auto p : lst) {
        delete widget->takeTopLevelItem(widget->indexOfTopLevelItem(p));
    }
}

// 任务全选
void MainWindow::on_buttonSelectAll_clicked() {
    QTreeWidget* widget = this->ui->treeUrls;

    int ct = widget->topLevelItemCount();
    for (int i = 0; i < ct; ++i) {
        widget->topLevelItem(i)->setCheckState(1, Qt::Checked);
    }
}

// 任务全不选
void MainWindow::on_buttonSelectNone_clicked() {
    QTreeWidget* widget = this->ui->treeUrls;

    int ct = widget->topLevelItemCount();
    for (int i = 0; i < ct; ++i) {
        widget->topLevelItem(i)->setCheckState(1, Qt::Unchecked);
    }
}

// 提取真实链接
void MainWindow::on_buttonSniff_clicked() {
    QTreeWidget* widget = this->ui->treeUrls;
    int count = widget->topLevelItemCount();

    if (count == 0) {
        return;
    }

    YDUrlSniffer::job_t job;

    for (auto i = 0; i < count; ++i) {
        QTreeWidgetItem* item =widget->topLevelItem(i);

        if (item->checkState(1) != Qt::Checked) {
            continue;
        }

        QString type = item->data(0, Qt::UserRole).toString();

        if (job.end() == job.find(type)) {
            job[type] = QStringList {item->text(2)};
        } else {
            job[type].append(item->text(2));
        }
    }

    if (!job.empty()) {
        YDUrlSniffer* sniffer = new YDUrlSniffer(this);

        connect(sniffer, &YDUrlSniffer::progressChanged,
            this, &MainWindow::on_sniffer_progressChanged);
        connect(sniffer, &YDUrlSniffer::finished,
            this, &MainWindow::on_sniffer_finished);
        sniffer->sniff(job);
        dlgProgress->exec();
    }
}

// 添加链接
void MainWindow::on_buttonAddUrl_clicked() {
    int code = dlgAdd->exec();

    if (QDialog::Rejected == code) {
        return;
    }

    QString str = dlgAdd->url();
    QTreeWidget* widget = this->ui->treeUrls;

    if (!str.isEmpty()) {
        YDUrlRecogniser::url_map_t map = g.urlRecogniser->recogniseUrl(str);

        for (auto p : map) {
            for (auto s : p.second) {
                // 确保没有重复的
                if (!widget->findItems(s, Qt::MatchFixedString, 2).isEmpty()) {
                    continue;
                }

                QTreeWidgetItem* item = new QTreeWidgetItem;

                item->setFlags(item->flags() | Qt::ItemIsEditable);

                item->setText(0, g.diskMap->getText(p.first));
                item->setIcon(0, *g.diskMap->getIcon(p.first));
                item->setData(0, Qt::UserRole, QVariant(p.first)); // 存储网盘类型，以备以后使用
                item->setCheckState(1, Qt::Checked);
                item->setText(2, s);
                widget->addTopLevelItem(item);
            }
        }
    }
}

// 将选定的任务真实链接复制到剪贴板
void MainWindow::on_buttonToClipboard_clicked() {
    QTreeWidget* widget = this->ui->treeUrls;
    int count = widget->topLevelItemCount();
    QString data = "";

    for (auto i = 0; i < count; ++i) {
        QTreeWidgetItem* item = widget->topLevelItem(i);
        if ((item->checkState(1) == Qt::Checked) && (item->text(3) != "提取错误")) {
            QString str = item->text(3);
            data += str;
            data += "\n";
        }
    }

    qApp->clipboard()->setText(data);
}

// 增加下载任务，直接转到“增加任务”页面
void MainWindow::on_buttonAddTask_clicked() {
    this->ui->tabWidget->setCurrentIndex(1);
    this->ui->buttonAddUrl->click();
}

// 从网页获取
void MainWindow::on_buttonGetFromWeb_clicked() {
    if (QDialog::Accepted == this->dlgGetFromWeb->exec()) {
        QString url = this->dlgGetFromWeb->url();

        if (!url.isEmpty()) {
            this->ui->webView->setUrl(url);
        }
    }
}

#include <QTimer>
void MainWindow::on_webview_load_finished() {
    this->ui->treeUrls->clear();

    QString html = this->ui->webView->page()->mainFrame()->toHtml();

#ifndef NDEBUG
    QString filename = "C:\\ydhelperdebug\\" + QTime::currentTime().toString("hh_mm_ss_zzz") + ".html";
    QFile f(filename, this);
    f.open(QIODevice::ReadWrite);
    f.write(html.toUtf8());
    f.close();
#endif

    if (!html.isEmpty()) {
        html = g.unescape(html);
        YDUrlRecogniser::url_map_t map = g.urlRecogniser->recogniseUrl(html);

        for (auto p : map) {
            for (auto s : p.second) {
                QTreeWidgetItem* item = new QTreeWidgetItem;

                item->setFlags(item->flags() | Qt::ItemIsEditable);

                item->setText(0, g.diskMap->getText(p.first));
                item->setIcon(0, *g.diskMap->getIcon(p.first));
                item->setData(0, Qt::UserRole, QVariant(p.first)); // 存储网盘类型，以备以后使用
                item->setCheckState(1, Qt::Checked);
                item->setText(2, s);
                this->ui->treeUrls->addTopLevelItem(item);
            }
        }
    }
}

void MainWindow::on_webView_load_started() {
    qDebug() << "on_webview_load_started: " << this->ui->webView->url();
}

void MainWindow::on_webView_load_progress(int pgr) {
    qDebug() << "on_webview_load_progress: " << pgr;
    this->dlgProgress->setProgress(pgr);
}
